package com.example.demo.common;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * 统一返回结果包装类
 * 默认成功，异常时设置 code 和 message
 * 
 * @author zhang
 * @date 2024
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 响应状态码（默认 200 成功）
     */
    private Integer code = 200;
    
    /**
     * 响应消息（默认操作成功）
     */
    private String message = "操作成功";
    
    /**
     * 响应数据
     */
    private T data;
    
    /**
     * 总记录数
     */
    private Long total;
    
    /**
     * 当前页码
     */
    private Integer pageNum;
    
    /**
     * 每页记录数
     */
    private Integer pageSize;
    
    /**
     * 总页数
     */
    private Integer totalPages;
    
    /**
     * 成功状态码
     */
    public static final int SUCCESS_CODE = 200;
    
    /**
     * 失败状态码
     */
    public static final int ERROR_CODE = 500;
    
    /**
     * 创建成功结果（使用默认值）
     */
    public static <T> Result<T> create() {
        return new Result<>();
    }
    
    /**
     * 创建成功结果（带数据）
     */
    public static <T> Result<T> create(T data) {
        Result<T> result = new Result<>();
        result.setData(data);
        return result;
    }
    
    /**
     * 创建成功结果（带分页信息）
     */
    public static <T> Result<T> create(T data, Long total, Integer pageNum, Integer pageSize) {
        Result<T> result = new Result<>();
        result.setData(data);
        result.setTotal(total);
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        
        // 计算总页数
        if (total != null && pageSize != null && pageSize > 0) {
            result.setTotalPages((int) Math.ceil((double) total / pageSize));
        }
        
        return result;
    }
    
    /**
     * 判断是否成功
     */
    public boolean isSuccess() {
        return SUCCESS_CODE == this.code;
    }
    
    /**
     * 设置错误信息
     */
    public Result error(Integer code, String message) {
        this.code = code;
        this.message = message;
        return this;
    }
    
    /**
     * 设置错误信息（使用 ResultCode）
     */
    public Result error(ResultCode resultCode) {
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
        return this;
    }
    
    /**
     * 设置自定义错误信息
     */
    public Result error(String message) {
        this.code = ERROR_CODE;
        this.message = message;
        return this;
    }
}
